<script setup lang="tsx">
import { computed, reactive, ref } from 'vue'
import { Dialog } from '@/components/Dialog'
import { PasswordStrength, Strength, UpdatePassword } from '@/api/system/types'
import { ElForm, ElMessage, FormInstance, FormRules } from 'element-plus'
import { useDesign } from '@/hooks/web/useDesign'
import { updateUserPwdApi } from '@/api/system/user'
import { UserLoginType } from '@/api/login/types'
import { sm2Encrypt, sm3Encrypt } from '@/utils/crypto'

const props = defineProps({
  modelValue: {
    type: Boolean
  }
})

const emit = defineEmits(['update:modelValue'])
const dialogVisible = computed({
  get: () => props.modelValue,
  set: (val) => {
    emit('update:modelValue', val)
  }
})

const updatePwd = reactive<UpdatePassword>({
  oldLoginPwd: '',
  newLoginPwd: ''
})
const validateNewLoginPwd = (rule, value, callback) => {
  if (value === undefined || value === null || value === '') {
    callback(new Error('新密码不能为空'))
  } else {
    if (value.length > 16 || value.length < 8) {
      callback(new Error('密码必须是8到16位'))
    }
    let reg = /^[A-Za-z0-9]+$/
    if (!reg.test(value)) {
      callback(new Error('密码必须是数字或英文字母的组合'))
    }
    callback()
  }
}
const checkPasswordStrength = (value: string) => {
  const mode = getPasswordStrengthMode(value)
  showPasswordStrength(mode)
}

const getPasswordStrengthMode = (loginPwd: string) => {
  let mode = 0
  let numberRegex = /^.*[0-9].*$/
  if (numberRegex.test(loginPwd)) {
    mode++
  }
  let lowercaseCharRegex = /^.*[a-z].*$/
  let uppercaseCharRegex = /^.*[A-Z].*$/
  if (lowercaseCharRegex.test(loginPwd) || uppercaseCharRegex.test(loginPwd)) {
    mode++
  }
  if (lowercaseCharRegex.test(loginPwd) && uppercaseCharRegex.test(loginPwd)) {
    mode++
  }
  return mode
}

const showPasswordStrength = (mode: number) => {
  switch (mode) {
    //初始化状态
    case 0:
      oneStrength.percentage = 0
      twoStrength.percentage = 0
      threeStrength.percentage = 0
      break
    case 1:
      oneStrength.percentage = 100
      twoStrength.percentage = 0
      threeStrength.percentage = 0
      oneStrength.customColors = [{ color: '#f56c6c', percentage: 100 }]
      break
    case 2:
      oneStrength.percentage = 100
      twoStrength.percentage = 100
      threeStrength.percentage = 0
      oneStrength.customColors = [{ color: '#e6a23c', percentage: 100 }]
      twoStrength.customColors = [{ color: '#e6a23c', percentage: 100 }]
      break
    case 3:
      oneStrength.percentage = 100
      twoStrength.percentage = 100
      threeStrength.percentage = 100
      oneStrength.customColors = [{ color: '#67c23a', percentage: 100 }]
      twoStrength.customColors = [{ color: '#67c23a', percentage: 100 }]
      threeStrength.customColors = [{ color: '#67c23a', percentage: 100 }]
      break
    default:
      oneStrength.percentage = 0
      twoStrength.percentage = 0
      threeStrength.percentage = 0
      break
  }
}
const validateConfirmLoginPwd = (rule, value, callback) => {
  if (value === undefined || value === null || value === '') {
    callback(new Error('确认密码不能为空'))
  } else {
    if (value !== updatePwd.newLoginPwd) {
      callback(new Error('与新密码不一致'))
    } else {
      callback()
    }
  }
}
const rules = reactive<FormRules<UpdatePassword>>({
  oldLoginPwd: [{ required: true, trigger: 'blur', message: '原密码不能为空' }],
  newLoginPwd: [{ required: true, trigger: 'blur', validator: validateNewLoginPwd }],
  confirmLoginPwd: [{ required: true, trigger: 'blur', validator: validateConfirmLoginPwd }]
})
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('form')
const oneStrength = reactive<PasswordStrength>({
  percentage: 0,
  customColors: [{ color: '#f56c6c', percentage: 100 }]
})
const twoStrength = reactive<PasswordStrength>({
  percentage: 0,
  customColors: [{ color: '#f56c6c', percentage: 100 }]
})
const threeStrength = reactive<PasswordStrength>({
  percentage: 0,
  customColors: [{ color: '#f56c6c', percentage: 100 }]
})
const strength = reactive<Strength>({
  oneStrength: oneStrength,
  twoStrength: twoStrength,
  threeStrength: threeStrength,
  contentColor: '',
  content: ''
})
const loading = ref(false)
const pwdFormRef = ref<FormInstance>()
const updateUserPwd = async () => {
  loading.value = true
  await pwdFormRef.value?.validate(async (isValid) => {
    if (isValid) {
      const updatePwdParams: UpdatePassword = {
        oldLoginPwd: sm3Encrypt(updatePwd.oldLoginPwd.trim()),
        newLoginPwd: sm2Encrypt(updatePwd.newLoginPwd.trim())
      }
      const res = await updateUserPwdApi(updatePwdParams)
      if (res.code === 200) {
        ElMessage.success('修改成功')
        dialogVisible.value = false
      }
    }
    loading.value = false
  })
}
</script>
<template>
  <div>
    <Dialog v-model="dialogVisible" title="修改密码" style="width: 500px" maxHeight="180px">
      <el-form
        ref="pwdFormRef"
        :model="updatePwd"
        :rules="rules"
        label-width="100px"
        label-position="right"
        status-icon
        :class="prefixCls"
        style="padding-right: 50px; padding-top: 10px"
      >
        <el-row>
          <el-col>
            <el-form-item label="原密码" prop="oldLoginPwd">
              <el-input
                v-model="updatePwd.oldLoginPwd"
                type="password"
                show-password
                placeholder="请输入原密码"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col>
            <el-form-item label="新密码" prop="newLoginPwd">
              <el-input
                v-model="updatePwd.newLoginPwd"
                type="password"
                show-password
                @input="checkPasswordStrength"
                placeholder="请输入8-16位由数字、英文字母组合"
              />
              <div style="width: 100%; display: flex; margin-top: 5px">
                <div style="width: 31%">
                  <el-progress
                    :percentage="strength.oneStrength.percentage"
                    :color="strength.oneStrength.customColors"
                    :show-text="false"
                  />
                </div>
                <div style="width: 31%; margin-left: 3%">
                  <el-progress
                    :percentage="strength.twoStrength.percentage"
                    :color="strength.twoStrength.customColors"
                    :show-text="false"
                  />
                </div>
                <div style="width: 31%; margin-left: 3%">
                  <el-progress
                    :percentage="strength.threeStrength.percentage"
                    :color="strength.threeStrength.customColors"
                    :show-text="false"
                  />
                </div>
              </div>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col>
            <el-form-item label="确认密码" prop="confirmLoginPwd">
              <el-input
                v-model="updatePwd.confirmLoginPwd"
                type="password"
                show-password
                placeholder="请输入确认密码"
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <el-button type="primary" :loading="loading" @click="updateUserPwd">保存</el-button>
        <el-button @click="dialogVisible = false">取消</el-button>
      </template>
    </Dialog>
  </div>
</template>
